/**
 * Copyright (C), 2017-2018, XXX有限公司
 * FileName: EclipseASTTest
 * Author:   zengjian
 * Date:     2018/8/27 15:11
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 */
package fun.codedesign.yinxue.code.engine.jdt;

import org.eclipse.jdt.core.dom.*;


public class StatementTest {

    public static void main(String[] args) {
        
    }

    public static void printAstNode() {
        AST ast = AST.newAST(AST.JLS10);
        // ast factory?
        print("---a---");
        print(ast.newAssignment());
        print(ast.newAnnotationTypeDeclaration());
        print(ast.newAnnotationTypeMemberDeclaration());
        print(ast.newAnonymousClassDeclaration());
        print(ast.newArrayAccess());
        print(ast.newArrayCreation());
        print(ast.newArrayInitializer());

        print("---b---");
        print(ast.newBlock());
        print(ast.newBooleanLiteral(true));
        print(ast.newBlockComment());
        print(ast.newBreakStatement());

        print("---c---");
        print(ast.newCastExpression());
        print(ast.newCatchClause());
        print(ast.newCharacterLiteral());
        print(ast.newClassInstanceCreation());
        print(ast.newCompilationUnit());
        print(ast.newConditionalExpression());
        print(ast.newConstructorInvocation());
        print(ast.newContinueStatement());
        print(ast.newCreationReference());
        print("---ddd---");
        print(ast.newDimension());
        print(ast.newDoStatement());
        print("---eee---");
        print(ast.newEmptyStatement());
        print(ast.newEnhancedForStatement());
        print(ast.newEnumConstantDeclaration());
        print(ast.newEnumDeclaration());
        print(ast.newExportsStatement());
        print(ast.newExpressionMethodReference());
        print(ast.newExpressionStatement(ast.newCastExpression()));
        print("---fff---");
        print(ast.newFieldAccess());
        print(ast.newFieldDeclaration(ast.newVariableDeclarationFragment()));
        print(ast.newForStatement());
        print("---ggg---");
        print("---hhh---");
        print("---iii---");
        print(ast.newIfStatement());
        print(ast.newImportDeclaration());
        print(ast.newInfixExpression());
        print(ast.newInitializer());
        print(ast.newInstanceofExpression());
        print(ast.newIntersectionType());
        print("---jjj---");
        print(ast.newJavadoc());
        print("---kkk---");
        print("---lll---");
        print(ast.newLabeledStatement());
        print(ast.newLambdaExpression());
        print(ast.newLineComment());
        print("---mmm---");
        print(ast.newMarkerAnnotation());
        print(ast.newMemberRef());
        print(ast.newMemberValuePair());
        print(ast.newMethodDeclaration());
        print(ast.newMethodInvocation());
        print(ast.newMethodRefParameter());
        print(ast.newModifier(Modifier.ModifierKeyword.DEFAULT_KEYWORD));
        print(ast.newModifiers(2));
        print(ast.newModuleDeclaration());
        print(ast.newModuleModifier(ModuleModifier.ModuleModifierKeyword.STATIC_KEYWORD));
        print("---nnn---");
        print(ast.newName("HELLO"));
        print(ast.newName(new String[]{"hello", "hi"}));
        print(ast.newNameQualifiedType(ast.newName("Hi"), ast.newSimpleName("Hello")));
        print(ast.newName("Hello"));
        print(ast.newName(new String[]{"Hello1", "hello2"}));
        print(ast.newNormalAnnotation());
        print(ast.newNullLiteral());
        print(ast.newNumberLiteral());
        print(ast.newNumberLiteral("1"));
        print("---ooo---");
        print(ast.newOpensDirective());
        print("---ppp---");
        print(ast.newPackageDeclaration());
        print(ast.newParameterizedType(ast.newSimpleType(ast.newName("Hello"))));
        print(ast.newParenthesizedExpression());
        print(ast.newPostfixExpression());
        print(ast.newPrefixExpression());
        print(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
        print(ast.newProvidesDirective());
        print("---qqq---");
        print(ast.newQualifiedName(ast.newName("Hi"), ast.newSimpleName("Hello")));
        print(ast.newQualifiedType(ast.newSimpleType(ast.newName("Hi")), ast.newSimpleName("Hello")));
        print("---rrr---");
        print(ast.newRequiresDirective());
        print(ast.newReturnStatement());
        print("---sss---");
        print(ast.newSimpleName("Hi"));
        print(ast.newSimpleType(ast.newName("Hi")));
        print(ast.newSingleMemberAnnotation());
        print(ast.newSingleVariableDeclaration());
        print(ast.newStringLiteral());
        print(ast.newSuperConstructorInvocation());
        print(ast.newSuperFieldAccess());
        print(ast.newSuperMethodInvocation());
        print(ast.newSuperMethodReference());
        print(ast.newSwitchCase());
        print(ast.newSwitchStatement());
        print(ast.newSynchronizedStatement());
        print("---ttt---");
        print(ast.newTagElement());
        print(ast.newTextElement());
        print(ast.newThisExpression());
        print(ast.newThrowStatement());
        print(ast.newTryStatement());
        print(ast.newTypeDeclaration());
        print(ast.newTypeDeclarationStatement(ast.newTypeDeclaration()));
        print(ast.newTypeLiteral());
        print(ast.newTypeMethodReference());
        print("---uuu---");
        print(ast.newUnionType());
        print(ast.newUsesDirective());
        print("---vvv---");
        print(ast.newVariableDeclarationExpression(ast.newVariableDeclarationFragment()));
        print(ast.newVariableDeclarationFragment());
        print(ast.newVariableDeclarationStatement(ast.newVariableDeclarationFragment()));
        print("---www---");
        print(ast.newWhileStatement());
        print(ast.newWildcardType());
        print("---xxx---");
        print("---yyy---");
        print("---zzz---");
    }


    /**
     *
     * <pre><code>
     * {
     * 	m=12;
     * 	n=21;
     * 	if(m<n)
     *    {t=m;m=n;n=t;
     *    }
     * 	r=m%n;
     * 	while(r!=0)
     *    {m=n;n=r;r=m%n;}
     * 	print(n);
     * }
     * </code></pre>
     *
     * @return Block
     * @throws
     * @since 1.0.0
     */

    public static void testBlock2() {
        AST ast = AST.newAST(AST.JLS10);
        Assignment assign;
        ExpressionStatement ex;
        InfixExpression infixEx;

        //main 
        Block block = ast.newBlock();
        //m=12
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("m"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newNumberLiteral("12"));
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        //n=15
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("n"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newNumberLiteral("15"));
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        //m<n
        infixEx = ast.newInfixExpression();
        infixEx.setLeftOperand(ast.newSimpleName("m"));
        infixEx.setRightOperand(ast.newSimpleName("n"));
        infixEx.setOperator(InfixExpression.Operator.LESS);
        Block ifbody = ast.newBlock();
        //t=m
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("t"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newSimpleName("m"));
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        //m=n
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("m"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newSimpleName("n"));
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        //n=t
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("n"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newSimpleName("t"));
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        IfStatement ifst = ast.newIfStatement();
        ifst.setExpression(infixEx);
        ifst.setThenStatement(ifbody);
        block.statements().add(ifst);

        //r=m%n
        infixEx = ast.newInfixExpression();
        infixEx.setLeftOperand(ast.newSimpleName("m"));
        infixEx.setRightOperand(ast.newSimpleName("n"));
        infixEx.setOperator(InfixExpression.Operator.REMAINDER);
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("r"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(infixEx);
        ex = ast.newExpressionStatement(assign);
        block.statements().add(ex);

        //while
        WhileStatement whilest = ast.newWhileStatement();
        infixEx = ast.newInfixExpression();
        infixEx.setLeftOperand(ast.newSimpleName("r"));
        infixEx.setRightOperand(ast.newNumberLiteral("0"));
        infixEx.setOperator(InfixExpression.Operator.NOT_EQUALS);
        whilest.setExpression(infixEx);
        Block whilebody = ast.newBlock();
        //m=n
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("m"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newSimpleName("n"));
        ex = ast.newExpressionStatement(assign);
        whilebody.statements().add(ex);
        //n=r
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("n"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(ast.newSimpleName("r"));
        ex = ast.newExpressionStatement(assign);
        whilebody.statements().add(ex);
        //r=m%n
        infixEx = ast.newInfixExpression();
        infixEx.setLeftOperand(ast.newSimpleName("m"));
        infixEx.setRightOperand(ast.newSimpleName("n"));
        infixEx.setOperator(InfixExpression.Operator.REMAINDER);
        assign = ast.newAssignment();
        assign.setLeftHandSide(ast.newSimpleName("r"));
        assign.setOperator(Assignment.Operator.ASSIGN);
        assign.setRightHandSide(infixEx);
        ex = ast.newExpressionStatement(assign);
        whilebody.statements().add(ex);
        whilest.setBody(whilebody);
        block.statements().add(whilest);

        //print
        MethodInvocation p1 = ast.newMethodInvocation();
        p1.setName(ast.newSimpleName("print"));
        p1.arguments().add(ast.newSimpleName("n"));
        ex = ast.newExpressionStatement(p1);
        block.statements().add(ex);
        print(block);
    }

    static void print(Object src) {
        System.out.println(src);
        System.out.println("******");
    }

}